<template>
  <PageWrapper dense contentFullHeight fixedHeight>
    <BasicTable @register="registerTable">
      <template #form-classifyId="{ model, field }">
        <a-cascader v-model:value="model[field]" :options="options" placeholder="请选择"
          :fieldNames="{ label: 'classifyName', value: 'classifyId' }" />
      </template>
      <template #toolbar>
        <a-button type="primary" @click="handleCreate">新增</a-button>
        <a-button type="primary" :disabled="selectedRowKeys.length === 0" @click="handleBatchDelete">批量删除</a-button>
      </template>
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'action'">
          <TableAction :actions="createActions(record)" />
        </template>
      </template>
    </BasicTable>
    <ModalAddRecord @register="registerModal" @success="handleSuccess" />
  </PageWrapper>
</template>
<script setup lang="ts">
import { PageWrapper } from '@/components/Page'
import { BasicTable, useTable, TableAction, EditRecordRow, ActionItem } from '@/components/Table'
import { getBudgetList, updateBudgetRecord, deleteBudgetList } from '@/api/sys/budgetData'
import { searchFormSchema } from './data'
import { ref, createVNode, onMounted } from 'vue'
import { useModal } from '@/components/Modal'
import { cloneDeep, last } from 'lodash-es'
import { useMessage } from '@/hooks/web/useMessage'
import { message, Modal } from 'ant-design-vue'
import { Key } from 'ant-design-vue/es/table/interface'
import ModalAddRecord from './ModalAddRecord.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
import { getDictListByCodeAndName } from '@/api/sys/dict'
import { getClassifyTreeByPatent } from '@/api/collection/classify'

defineOptions({ name: 'BudgetData' })
const { createMessage: msg } = useMessage()
const currentEditKeyRef = ref('')
const selectedRowKeys = ref<Key[]>([])
const options = ref([])

const [registerTable, { setColumns, reload, updateTableDataRecord }] = useTable({
  title: '预算数据',
  // 经测试，这里设置了 rowKey，保存表格一次或者搜索表格或者翻页之后，行内 record 没有 edit 的相关方法，导致表格无法编辑
  // rowKey: 'id',
  api: getBudgetList,
  columns: [],
  useSearchForm: true,
  size: 'small',
  formConfig: {
    labelWidth: 80,
    schemas: searchFormSchema,
    autoSubmitOnEnter: true,
  },
  bordered: true,
  striped: true,
  actionColumn: {
    width: 120,
    title: '操作',
    dataIndex: 'action',
  },
  beforeFetch: (params) => ({
    ...params,
    classifyId: last(params.classifyId),
  }),
  afterFetch: (data) => {
    if (data.length > 0) {
      formatHeader(data[0].monthList)
    }
  },
  rowSelection: {
    onChange: (selectedKeys, selectedData) => {
      selectedRowKeys.value = selectedData.map((item) => item.id)
    },
  },
})
const [registerModal, { openModal }] = useModal()

function createActions(record: EditRecordRow): ActionItem[] {
  if (!record.editable) {
    return [
      {
        label: '编辑',
        disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.id : false,
        onClick: handleEdit.bind(null, record),
      },
      {
        label: '删除',
        color: 'error',
        disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.id : false,
        popConfirm: {
          title: '确认删除',
          confirm: handleDelete.bind(null, record),
        },
      },
    ]
  }
  return [
    {
      label: '保存',
      onClick: handleSave.bind(null, record),
    },
    {
      label: '取消',
      onClick: handleCancel.bind(null, record),
    },
  ]
}

const formatHeader = (headerData) => {
  const headerList = headerData.map((item) => ({
    title: item,
    dataIndex: ['budgetValueVOs', item, 'budgetVal'],
    width: 100,
    editRow: true,
    editComponent: 'InputNumber',
    editRender: ({ text }) => {
      return text === null ? '--' : text
    },
  }))
  headerList.unshift(
    {
      title: '标签名',
      dataIndex: 'tag',
      width: 170,
      fixed: 'left',
    },
    {
      title: '年份',
      dataIndex: 'budgetYear',
      width: 120,
      fixed: 'left',
    },
  )

  setColumns(headerList)
}

onMounted(() => {
  getOptions()
})

const getOptions = async () => {
  const parentData = await getDictListByCodeAndName({
    code: 'budget_manage',
    itemName: 'tree_id',
  })
  const data = await getClassifyTreeByPatent({ parentClassifyId: parentData.itemCode })
  options.value = data
}

const handleCancel = (record: EditRecordRow) => {
  currentEditKeyRef.value = ''
  record.onEdit?.(false, false)
}

const handleEdit = (record) => {
  currentEditKeyRef.value = record.key
  record.onEdit?.(true)
}

const formatEditedData = (editedData, budgetValueVOs) => {
  const rowData = cloneDeep(budgetValueVOs)
  for (const key in editedData) {
    const [, subKey, field] = key.split(',')

    if (rowData[subKey]) {
      // 编辑的单元格没有值，为null
      if (editedData[key] === null) {
        // 如果原来有值，但是删掉了，要置成0，根据有budgetMonth判断原来有值
        if (rowData[subKey].budgetMonth) {
          rowData[subKey][field] = 0
        } else {
          delete rowData[subKey]
        }
      } else {
        // 确保每一条有效数据都有budgetMonth
        rowData[subKey] = {
          ...rowData[subKey],
          [field]: editedData[key],
          budgetMonth: parseFloat(subKey),
        }
      }
    }
  }

  return Object.values(rowData)
}

const handleSave = async (record) => {
  // 校验
  const valid = await record.onValid?.()
  if (valid) {
    const editData = cloneDeep(record.editValueRefs)!
    const budgetValDTOList = formatEditedData(editData, record.budgetValueVOs)
    const data = {
      budgetDefId: record.id,
      budgetValDTOList,
    }
    await updateBudgetRecord(data)

    const pass = await record.onEdit?.(false, true)
    if (pass) {
      currentEditKeyRef.value = ''
    }
    msg.success({ content: '数据已保存', key: 'saving' })
    reload()
  } else {
    msg.error({ content: '请填写正确的数据', key: 'saving' })
  }
}

const handleBatchDelete = () => {
  Modal.confirm({
    title: '提示',
    icon: createVNode(ExclamationCircleOutlined),
    content: '确认删除吗？',
    onOk() {
      deleteFn(selectedRowKeys.value.join(','), true)
    },
    onCancel() {
      return
    },
  })
}

const handleDelete = (record) => {
  deleteFn(record.id)
}

const deleteFn = (ids, isBatch = false) => {
  deleteBudgetList(`?ids=${ids}`).then((res) => {
    message.success('删除成功')
    reload()
    if (isBatch) {
      selectedRowKeys.value = []
    }
  })
}

const handleCreate = () => {
  openModal(true, {
    isUpdate: false,
  })
}
// 添加成功
const handleSuccess = ({ isUpdate, values }) => {
  if (isUpdate) {
    // 演示不刷新表格直接更新内部数据。
    // 注意：updateTableDataRecord要求表格的rowKey属性为string并且存在于每一行的record的keys中
    const result = updateTableDataRecord(values.id, values)
    console.log(result)
  } else {
    reload()
  }
}
</script>
<style scoped lang="scss">
:deep(.ant-input-number) {
  min-width: 80px;
}
</style>
